package com.ejlchina.tool.fragment

import android.graphics.Color
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.adolf.androiddemo.databinding.FragmentLightAndVolumeBinding
import com.huyuhui.fastble.data.BleDevice
import com.ejlchina.tool.adapter.DeviceAdapterRadio
import com.ejlchina.tool.adapter.LightTimeAdapter
import com.ejlchina.tool.base.BaseBindingFragment2
import com.ejlchina.tool.bean.BleDeviceBean
import com.ejlchina.tool.bean.LightTimeBean
import com.ejlchina.tool.bean.TimeBean
import com.ejlchina.tool.enums.LightTimeGetEnum
import com.ejlchina.tool.enums.OnOffEnum
import com.ejlchina.tool.singleton.GlobalConnectObject
import com.ejlchina.tool.util.COMMAND_LIGHT_TIME_GET_DOWNWARD
import com.ejlchina.tool.util.COMMAND_LIGHT_TIME_GET_UPWARD
import com.ejlchina.tool.util.COMMAND_LIGHT_TIME_SET_DOWNWARD
import com.ejlchina.tool.util.COMMAND_LIGHT_TIME_SET_UPWARD
import com.ejlchina.tool.util.COMMAND_VOLUME_GET_DOWNWARD
import com.ejlchina.tool.util.COMMAND_VOLUME_GET_UPWARD
import com.ejlchina.tool.util.COMMAND_VOLUME_SET_DOWNWARD
import com.ejlchina.tool.util.COMMAND_VOLUME_SET_UPWARD
import com.ejlchina.tool.util.LOG_TAG
import com.ejlchina.tool.util.bytearray.intTo16HexStringLE
import com.ejlchina.tool.util.bytearray.intToByteHexString
import com.ejlchina.tool.util.bytearray.readUInt16LE
import com.ejlchina.tool.view.GridItemDecoration
import com.ejlchina.tool.view.HorizontalItemDecoration
import com.litao.slider.effect.ITEffect
import com.loper7.date_time_picker.DateTimeConfig
import com.loper7.date_time_picker.dialog.CardDatePickerDialog
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.Calendar

class LightAndVolumeFragment: BaseBindingFragment2<FragmentLightAndVolumeBinding>() {

    private val lightTimeList = mutableListOf<LightTimeBean>()
    private lateinit var lightTimeAdapter :LightTimeAdapter

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initViews()
        initData()
    }

    private fun initViews(){
        setHeadTitle("照明音量")
        setRightIconVisibility(View.GONE)
        initListeners()
    }

    private fun initDevices(){
        deviceAdapter = DeviceAdapterRadio(GlobalConnectObject.getCurrentConnectDeviceList()){
            viewLifecycleOwner.lifecycleScope.launch {
                getLightData(it)
                delay(600)
                getVolumeData(it)
            }
        }
        binding.rvDevices.apply {
            adapter = deviceAdapter
            layoutManager = GridLayoutManager(requireContext(), 3)
            if (itemDecorationCount == 0) {
                addItemDecoration(GridItemDecoration(3, 11, 11))
            }
        }
    }

    private fun showLightTimeSelectDialog(isStartTime: Boolean, position: Int) {
        val title = if (isStartTime) "请选择开始时间" else "请选择结束时间"
        CardDatePickerDialog.builder(requireContext())
            .setTitle(title)
            .showBackNow(false)
            .showFocusDateInfo(false)
            .setBackGroundModel(CardDatePickerDialog.STACK)
            .setDisplayType(DateTimeConfig.HOUR, DateTimeConfig.MIN)
            .setThemeColor(Color.BLUE)
            .setOnChoose { millisecond ->
                val calendar = Calendar.getInstance()
                calendar.timeInMillis = millisecond
                val timeBean = if (isStartTime) lightTimeList[position].startTime else lightTimeList[position].endTime
                timeBean.apply {
                    hour = calendar.get(Calendar.HOUR_OF_DAY)
                    minute = calendar.get(Calendar.MINUTE)
                }
                lightTimeAdapter.notifyDataSetChanged()
            }.build().show()
    }

    private fun initListeners(){

        binding.layoutAddLightTime.setOnClickListener {
            lightTimeList.clear()
            lightTimeList.add(LightTimeBean())
            lightTimeAdapter.notifyDataSetChanged()
            it.visibility = View.GONE
        }

        binding.btnConfirm.setOnClickListener {
            setLightTimeData(deviceAdapter.getSelectDevice())
        }

        binding.switchLight.setOnCheckedChangeListener { _, isChecked ->
            binding.layoutLightTimeSetting.visibility = if (isChecked) View.GONE else View.GONE
        }
    }

    override fun whenReceiveCommand(bleDevice: BleDeviceBean,command: String, dataByteArray: ByteArray) {
        super.whenReceiveCommand(bleDevice,command, dataByteArray)
        dismissLoading()
        when(command){
            COMMAND_LIGHT_TIME_GET_UPWARD -> {
                handleLightDataUI(dataByteArray)
            }
            COMMAND_LIGHT_TIME_SET_UPWARD -> {
                setResultToast(dataByteArray[dataByteArray.size - 1].toInt())
                viewLifecycleOwner.lifecycleScope.launch {
                    delay(300)
                    setVolumeData(deviceAdapter.getSelectDevice())
                }
            }
            COMMAND_VOLUME_GET_UPWARD -> {
                binding.slideVolume.setValue(dataByteArray[0].toInt().toFloat(),true)
                dismissLoading()
            }

            COMMAND_VOLUME_SET_UPWARD -> {
                setResultToast(dataByteArray[dataByteArray.size - 1].toInt())
            }
        }
    }

    private fun initData(){
        initDevices()
        initLightTime()
        binding.slideVolume.apply {
            effect = ITEffect(this).apply {
                valueFrom = 0F
                valueTo = 15F
            }
            addOnIntValueChangeListener { slider, value, fromUser ->
                setThumbText(value.toString())
            }
        }
    }

    private fun formatLightTime(timeValue: Int): TimeBean{
        return TimeBean(timeValue / 60,timeValue % 60)
    }

    private fun timeBeanToInt(timeBean: TimeBean): Int{
        return timeBean.hour * 60 + timeBean.minute
    }

    private fun initLightTime(){
        lightTimeAdapter= LightTimeAdapter(lightTimeList,
            startTimeClick = { position ->
                showLightTimeSelectDialog(true,position)
            }, endTimeClick = { position ->
                showLightTimeSelectDialog(false,position)
            }, removeClick = {position ->
                lightTimeList.removeAt(position)
                lightTimeAdapter.notifyDataSetChanged()
                binding.layoutAddLightTime.visibility = View.VISIBLE
            })
        binding.rvLightTime.apply {
            adapter = lightTimeAdapter
            layoutManager = object : LinearLayoutManager(requireContext()){
                override fun canScrollVertically(): Boolean {
                    return false
                }
            }
            isNestedScrollingEnabled = false
            if (itemDecorationCount == 0){
                addItemDecoration(HorizontalItemDecoration())
            }
        }
    }

    private fun setLightTimeData(bleDevice: BleDeviceBean){
        val lightMode = getLightMode()
        val isCloseAutoLight = if (lightTimeList.size > 0 && binding.switchLight.isChecked) 1 else 0
        val beginTime = getLightStartEndTime(true)
        val endTime = getLightStartEndTime(false)

        val commandDataString = StringBuffer()
        commandDataString.append(intToByteHexString(lightMode.value))
        commandDataString.append(intToByteHexString(isCloseAutoLight))
        commandDataString.append(intTo16HexStringLE(beginTime))
        commandDataString.append(intTo16HexStringLE(endTime))
        setCommandData(bleDevice, COMMAND_LIGHT_TIME_SET_DOWNWARD,commandDataString.toString())
    }

    private fun getLightMode(): LightTimeGetEnum{
        return if (binding.switchLight.isChecked){
            return if (lightTimeList.isEmpty()) LightTimeGetEnum.LIGHT_ON else LightTimeGetEnum.LIGHT_SET
        }else {
            return LightTimeGetEnum.LIGHT_OFF
        }
    }

    private fun getLightStartEndTime(isStartTime: Boolean): Int{
        return if (binding.switchLight.isChecked){
            if (lightTimeList.size > 0){
                val timeBean = if (isStartTime) lightTimeList[0].startTime else lightTimeList[0].endTime
                timeBean.hour * 60 + timeBean.minute
            }else {
                0
            }
        }else {
            0
        }
    }

    private fun getLightData(bleDevice: BleDeviceBean){
        getCommandData(bleDevice, COMMAND_LIGHT_TIME_GET_DOWNWARD)
    }

    private fun handleLightDataUI(byteArray: ByteArray){
        val onOffMode = byteArray[0].toInt() != LightTimeGetEnum.LIGHT_OFF.value
        val autoLightState = byteArray[1].toInt() == OnOffEnum.ON.value
        setLightOnOffState(onOffMode)
        if (autoLightState){
            val lightTimeBean = LightTimeBean()
            lightTimeBean.startTime = formatLightTime(byteArray.copyOfRange(2,4).readUInt16LE())
            lightTimeBean.endTime = formatLightTime(byteArray.copyOfRange(4,6).readUInt16LE())
            lightTimeList.clear()
            lightTimeList.add(lightTimeBean)
            lightTimeAdapter.notifyDataSetChanged()
            binding.layoutAddLightTime.visibility = View.GONE
        }else {
            binding.layoutAddLightTime.visibility = View.VISIBLE
        }
    }

    private fun setLightOnOffState(isOn: Boolean){
        binding.switchLight.isChecked = isOn
        binding.layoutLightTimeSetting.visibility = if (isOn) View.GONE else View.GONE
    }

    private fun getVolumeData(bleDevice: BleDeviceBean){
        getCommandData(bleDevice, COMMAND_VOLUME_GET_DOWNWARD)
    }

    private fun setVolumeData(bleDevice: BleDeviceBean){
        setCommandData(bleDevice,COMMAND_VOLUME_SET_DOWNWARD, getVolumeResultData())
    }



    private fun getVolumeResultData(): String{
        return intToByteHexString(binding.slideVolume.value.toInt())
    }
    override fun getViewBinding(inflater: LayoutInflater, container: ViewGroup): FragmentLightAndVolumeBinding {
        return FragmentLightAndVolumeBinding.inflate(inflater,container,true)
    }
}